package com.kdg;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Created by Administrator on 2017/8/22.
 * 1.String列表排序的java8之前和java8比较
 * 2.函数式编程
 *       {
 *           tips1.一个所谓的函数式接口必须要有且仅有一个抽象方法声明。
 *       }
 * 3.Lambda表达式
 * 4.  :关键字引用构造函数
 * 5.lambda表达式外部变量的访问权限与匿名内部类十分相似，能访问外部定义的final变量、成员变量、静态变量
 */
public class TestLambda {

    static int chengNum;
    int yuanNum;

    public static void main(String[] args) {
        List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");

        //java8之前写法
        /*Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });*/
        //java8写法
        /*lambda表达式写法1*/
        /*Collections.sort(names,(String a, String b) -> {
            return b.compareTo(a);
        });*/
        /*lambda表达式写法2*/
//        Collections.sort(names,(String a, String b) -> a.compareTo(b));
        //更简便写法  ---> Java编译器能够自动识别参数的类型，所以你就可以省略掉类型不写。
        Collections.sort(names, (a,b) -> a.compareTo(b));

        /**********************************************/
        for(String a:names){
            System.out.println(a);
        }
        /*********************2*************************/

//        Convertor<String,Integer> convertor = (from) -> Integer.valueOf(from);
        Convertor<String, Integer> convertor = Integer::valueOf;  //Java 8 允许你通过::关键字获取方法或者构造函数的的引用。
        Integer res1 = convertor.convertor("123");
        System.out.println(res1.getClass());

        /*********************3*************************/
        SomeThing someThing = new SomeThing();
        Convertor<String, String> converter = someThing::startWith;//someThing.startWith("HELLO");
        String hello = converter.convertor("HELLO");
        System.out.println(hello);

        /*********************4*************************/
        PersonFactory<Person> per = Person::new;
        Person person = per.create("kong", "degong");
        System.out.println(person.firstname+"--"+person.lastname);

        /*********************4*************************/
        //final int num =3;  //访问外部final变量
        int num = 4; //访问外部非final变量
        Convertor<String, Integer> convertor3 = (from) -> Integer.parseInt(from + num);
        Integer convertor1 = convertor3.convertor("3");
//        num = 3;  //虽然可以访问外部非final变量，但是编译器会将其隐式的看做final变量来处理；在lambda表达式内部企图改变num的值也是不允许的
        System.out.println(convertor1);
        //使用静态成员变量
        Convertor<String , Integer> con = (from) -> {
              chengNum = 23;
            return Integer.parseInt("3"+chengNum);
        };
    }

    void test(){
        //使用非静态成员变量
        Convertor<String, Integer> con2 = (from) ->{
            yuanNum = 10;
            return Integer.parseInt("4"+yuanNum);
        };
    }
}

interface Convertor<F, T>{
    T convertor(F from);
}

class SomeThing{
    String startWith(String a){
        return String.valueOf(a.charAt(2));
    }
}

class Person{
    String firstname;
    String lastname;

    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }
}

/**
 * person工厂接口   生产person
 * @param <P>
 */
interface PersonFactory<P extends Person>{
    P create(String firstname, String lastname);
}